package org.kl.auditsupervision.service.fnd;

import java.sql.Timestamp;
import java.util.Date;
import java.util.List;
import java.util.Map;

import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;

import org.activiti.engine.IdentityService;
import org.activiti.engine.RuntimeService;
import org.activiti.engine.delegate.DelegateExecution;
import org.activiti.engine.runtime.ProcessInstance;
import org.apache.commons.lang3.StringUtils;
import org.joda.time.DateTime;
import org.kl.auditsupervision.entity.fnd.AuditProDtl;
import org.kl.auditsupervision.entity.fnd.AuditProDtlNop;
import org.kl.auditsupervision.entity.fnd.Employee;
import org.kl.auditsupervision.repository.fnd.AuditProDtlNopDao;
import org.kl.auditsupervision.repository.fnd.OrgDao;
import org.kl.auditsupervision.repository.fnd.RiskDimensionStatisticDao;
import org.kl.auditsupervision.utils.AuditsupervisionConstants;
import org.kl.bf.entity.basic.User;
import org.kl.bf.service.BasicBpmService;
import org.kl.bf.service.BasicService;
import org.kl.bf.service.basic.DBProcessExecuteService;
import org.kl.bf.service.basic.UserService;
import org.kl.bf.utils.BasicConstants;
import org.kl.bf.utils.CRUDUtils;
import org.kl.bf.utils.KLDynamicSpecifications;
import org.kl.bf.web.base.BasicController;
import org.kl.bpm.entity.conf.BpmProcess;
import org.kl.bpm.service.conf.BpmKvPropService;
import org.kl.bpm.service.conf.BpmKvRecordService;
import org.kl.bpm.service.conf.BpmProcessService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

/**
 * @author Code Generator
 * @since 2016-08-02 17:07:38
 * @see 审计明细
 */
// Spring Bean的标识.
@Component
// 默认将类中的所有public函数纳入事务管理.
@Transactional
public class AuditProDtlNopService extends BasicService<AuditProDtlNop> {
	@Autowired
	private AuditProDtlNopDao auditProDtlNopDao;
	@Autowired
	private BpmProcessService bpmProcessService;
	@Autowired
	private BasicBpmService basicBpmService;
	@Autowired
	private IdentityService identityService;
	@Autowired
	private UserService userService;
	@Autowired
	private EmployeeService employeeService;
	@Autowired
	private DBProcessExecuteService dBProcessExecuteService;
	@Autowired
	private OrgDao orgDao;
	@Autowired
	private OrgService orgService;
	@Autowired
	private BpmKvRecordService bpmKvRecordService;
	@Autowired
	private BpmKvPropService bpmKvPropService;
	@Autowired
	private RuntimeService runtimeService;
	@Autowired
	private RiskDimensionStatisticDao riskDimensionStatisticDao;
	
	
	
	public String confirm(AuditProDtlNop auditProDtlNop) {
		auditProDtlNop.setConfirmMan(BasicController.getCurrentUserName());
		auditProDtlNop.setConfirmFlag(BasicConstants.CONFIRM_STATUS_Confirm);
		auditProDtlNop.setConfirmTime(new Timestamp(new Date().getTime()));
		auditProDtlNopDao.save(auditProDtlNop);

		return "确认成功";

	}
	
	/*

	/**
	 * 启动审批流程
	 * 
	 * @param researchProjectApply
	 * @param variables
	 * @return
	 */
	public ProcessInstance startWorkflow(AuditProDtlNop entity,
			Map<String, Object> variables) {

		String businessKey = entity.getId();
		String processDefinitionKey = null;
		 
		variables.put("workFlowFlag", "auditProDtl");//流程标记
		
		processDefinitionKey=AuditsupervisionConstants.PROCESS_DEFINITION_KEY_AUDIT;
		 
		BpmProcess bpmProcess = bpmProcessService
				.findByBpmConfBaseProcessDefinitionKey(processDefinitionKey);
		ProcessInstance processInstance = null;
		identityService.setAuthenticatedUserId(BasicController
				.getCurrentUserId());
		processInstance = basicBpmService.defaultProcess(bpmProcess, variables,
				businessKey);
		entity.setProcessInstanceId(processInstance.getProcessInstanceId());
		entity.setConfirmFlag(BasicConstants.CONFIRM_STATUS_Approving);
		auditProDtlNopDao.save(entity);
		return processInstance;
	}

	/**
	 * 流程正常结束
	 * 
	 * @param execution
	 * @param authenticatedUserId
	 */
	public void wflComplete(DelegateExecution execution,
			String authenticatedUserId) {
		String businessKey = execution.getProcessBusinessKey();
		if (StringUtils.isNotBlank(businessKey)) {
			AuditProDtlNop rpa = auditProDtlNopDao.getOne(businessKey);
			rpa.setConfirmFlag(BasicConstants.CONFIRM_STATUS_Confirm);
			rpa.setConfirmMan(BasicController.getCurrentUserName());
			rpa.setConfirmTime(new Timestamp(new DateTime().getMillis()));
			auditProDtlNopDao.save(rpa);
		}
	}
	
	/*public String workflowSelect(DelegateExecution execution,
			String authenticatedUserId){
		String businessKey = execution.getProcessBusinessKey();
		BpmKvRecord bpmKvRecord=bpmKvRecordService.findByBusinessId(businessKey);
		List<BpmKvProp> bpmKvPropList=bpmKvPropService.findByRecordIdAndPropCodeOrderByCreateTimeDesc(bpmKvRecord.getId(),"checkboxWF");
		String results="";
		String checkboxWF=bpmKvPropList.get(0).getValue();
		if(StringUtils.isBlank(checkboxWF)){
			checkboxWF="";
		}
	   if(checkboxWF.isEmpty()){
			results="0";
		}else{
			results="2";
		}

		return results;
	}
	
	public String workflowSelect2(DelegateExecution execution,
			String authenticatedUserId){
		String businessKey = execution.getProcessBusinessKey();
		BpmKvRecord bpmKvRecord=bpmKvRecordService.findByBusinessId(businessKey);
		List<BpmKvProp> bpmKvPropList=bpmKvPropService.findByRecordIdAndPropCodeOrderByCreateTimeDesc(bpmKvRecord.getId(),"checkboxWF");
		String results="";
		String checkboxWF=bpmKvPropList.get(0).getValue();
		if(checkboxWF.contains("学生科")){
			results="1";
		}else{
			results="0";
		}

		return results;
	}*/
	
	/**
	 * 发起人同意流程
	 * 
	 * @param execution
	 * @param authenticatedUserId
	 */
	public void wflAgree(DelegateExecution execution, String authenticatedUserId) {
		String businessKey = execution.getProcessBusinessKey();
		if (StringUtils.isNotBlank(businessKey)) {
			AuditProDtlNop rpa = auditProDtlNopDao.getOne(businessKey);
			rpa.setConfirmFlag(BasicConstants.CONFIRM_STATUS_Approving);
			auditProDtlNopDao.save(rpa);
		}
	}

	/**
	 * 流程不同意
	 * 
	 * @param execution
	 * @param authenticatedUserId
	 */
	public void wflDisagree(DelegateExecution execution,
			String authenticatedUserId) {
		String businessKey = execution.getProcessBusinessKey();
		if (StringUtils.isNotBlank(businessKey)) {
			AuditProDtlNop rpa = auditProDtlNopDao.getOne(businessKey);
			rpa.setConfirmFlag(BasicConstants.CONFIRM_STATUS_Draft);
			rpa.setConfirmMan(BasicController.getCurrentUserName());
			rpa.setConfirmTime(new Timestamp(new DateTime().getMillis()));
			auditProDtlNopDao.save(rpa);
		}
	}

	/**
	 * 流程取消
	 * 
	 * @param execution
	 * @param authenticatedUserId
	 */
	public void wflCancel(DelegateExecution execution,
			String authenticatedUserId) {
		String businessKey = execution.getProcessBusinessKey();
		if (StringUtils.isNotBlank(businessKey)) {
			AuditProDtlNop rpa = auditProDtlNopDao.getOne(businessKey);
			rpa.setConfirmFlag(BasicConstants.CONFIRM_STATUS_Cancel);
			rpa.setConfirmMan(BasicController.getCurrentUserName());
			rpa.setConfirmTime(new Timestamp(new DateTime().getMillis()));
			auditProDtlNopDao.save(rpa);
		}
	}

	public String multiDelete(String ids) {
		String[] idArray = StringUtils.split(ids, ",");
		int i = 0, z = 0;
		for (String id : idArray) {
			if (StringUtils.isNotBlank(id)) {
				AuditProDtlNop auditProDtl =auditProDtlNopDao.getOne(id);
				if (auditProDtl.getConfirmFlag() == BasicConstants.CONFIRM_STATUS_Draft) {
					auditProDtlNopDao.delete(id);
					i++;
				} else {
					/*String processInstanceId=auditProDtl.getProcessInstanceId();
					runtimeService.deleteProcessInstance(processInstanceId, "删除流程实例");
					auditProDtlNopDao.delete(id);*/
					z++;
				}
				//i++;
			}
		}
		return "删除" + i + "条明细信息,忽略"+z+"条已确认的明细信息";
	}
	
	/**
	 * 过滤
	 */
	public Page<AuditProDtlNop> getPageFilter(Map<String, Object> searchParams, int pageNumber, int pageSize, String sortType, String orderType,final String filterType,final String orgId) {
		PageRequest pageRequest = CRUDUtils.buildPageRequest(pageNumber, pageSize, sortType, orderType);
		final Specification<AuditProDtlNop> first = KLDynamicSpecifications.buildSpecification(searchParams, AuditProDtlNop.class);
		Specification<AuditProDtlNop> spec = new Specification<AuditProDtlNop>() {
			@Override
			public Predicate toPredicate(Root<AuditProDtlNop> root, CriteriaQuery<?> query, CriteriaBuilder cb) {
				Predicate[] plist = new Predicate[1];
				plist[0] = cb.equal(root.get("createBy").as(String.class), BasicController.getCurrentUserId());
				User user = userService.getUser(BasicController.getCurrentUserId());
				Predicate[] plist2 = new Predicate[1];
				plist2[0] = cb.equal(root.get("employee").as(Employee.class), user.getEmployee());
				if(filterType.equals("2")){
					String[] orgIdArray=orgId.split(",");
					Predicate[] plist3 = new Predicate[3+orgIdArray.length];
					plist3[0] = cb.equal(root.get("confirmFlag").as(Integer.class), 1);
					plist3[1] = cb.equal(root.get("confirmFlag").as(Integer.class), 2);
					plist3[2] = cb.equal(root.get("confirmFlag").as(Integer.class), 3);
					for(int i=0;i<=orgIdArray.length-1;i++){
						plist3[i+3] = cb.equal(root.get("createDept").as(String.class), orgIdArray[i]);
					}
					Predicate p1 = cb.or(cb.or(plist), cb.or(plist2));
					Predicate p = cb.or(p1, cb.or(plist3));
					
					return cb.and(first.toPredicate(root, query, cb), p);
				}else if(filterType.equals("1")){
					Predicate[] plist3 = new Predicate[3];
					plist3[0] = cb.equal(root.get("confirmFlag").as(Integer.class), 1);
					plist3[1] = cb.equal(root.get("confirmFlag").as(Integer.class), 2);
					plist3[2] = cb.equal(root.get("confirmFlag").as(Integer.class), 3);
					Predicate p1 = cb.or(cb.or(plist), cb.or(plist2));
					Predicate p = cb.or(p1, cb.or(plist3));
					return cb.and(first.toPredicate(root, query, cb), p);
				}else{
					Predicate p = cb.or(cb.or(plist), cb.or(plist2));
					return cb.and(first.toPredicate(root, query, cb), p);
				}
			}
		};
		return auditProDtlNopDao.findAll(spec, pageRequest);
	}

	public List<AuditProDtlNop> findByAuditProId(String auditProId) {
		 
		return auditProDtlNopDao.findByAuditProNopId(auditProId);
	}
	
	public List<AuditProDtlNop> findByAuditProIdAuditFindingEva(String auditProId,String auditFindingEva){
		return auditProDtlNopDao.findByAuditProNopIdAndAuditFindingEva(auditProId, auditFindingEva);
	}
	public List<AuditProDtlNop> findByAuditProIdAndAuditSuggestionFin(String auditProId,String auditSuggestionFin){
		return auditProDtlNopDao.findByAuditProNopIdAndAuditSuggestionFin(auditProId, auditSuggestionFin);
	}
	
	public List<AuditProDtlNop> findByAuditProNopIdAndAuditEvaluationNo(String auditProId,String auditEvaluationNo){
		 
		return auditProDtlNopDao.findByAuditProNopIdAndAuditEvaluationNo(auditProId, auditEvaluationNo);
	}
	
	public List<AuditProDtlNop> findByAuditProNopIdAndAuditEvaluationNoAndAuditFindingNo(String auditProNopId,String evalationNo,String auditFindingNo){
		return auditProDtlNopDao.findByAuditProNopIdAndAuditEvaluationNoAndAuditFindingNo(auditProNopId,evalationNo, auditFindingNo);
	}
	
}
